#pragma once

#include <berkelium\berkelium.hpp>
#include <berkelium\window.hpp>
#include <berkelium\windowdelegate.hpp>
#include <berkelium\widget.hpp>

#include "ContextWrapper.h"
#include "WidgetWrapper.h"
#include "WindowDelegateWrapper.h"

using namespace System;
using namespace Berkelium;

namespace BerkeliumDotNet
{
	ref class Widget;
	ref class Window;
	ref class WindowDelegate;
	class WindowDelegateWrapper;

	[Flags]
	public enum class KeyModifiers
	{
		/// <summary>No modifiers</summary>
		None = 0,
		ShiftMod = SHIFT_MOD,
		ControlMod = CONTROL_MOD,
		AltMod = ALT_MOD,
		MetaMod = META_MOD,
		/// <summary>If the key is on the keypad (use instead of keypad-specific keycodes)</summary>
		KeypadKey = KEYPAD_KEY,
		/// <summary>If this is not the first KeyPress event for this key</summary>
		AutoRepeatKey = AUTOREPEAT_KEY,
		/// <summary>if the keypress is a system event (WM_SYS* messages in windows)</summary>
		SystemKey = SYSTEM_KEY
	};

	public ref class Window : IDisposable
	{
	internal:
		Berkelium::Window* window;
		BerkeliumDotNet::WindowDelegateWrapper* windowDelegateWrapper;
		BerkeliumDotNet::WindowDelegate^ windowDelegate;

		Window();
		Window(Berkelium::Context* otherContext);
		Window(Berkelium::Window* window);

	public:
		~Window();

		property BerkeliumDotNet::Context^ Context
		{
			BerkeliumDotNet::Context^ get();
		}

		property BerkeliumDotNet::Widget^ Widget
		{
			BerkeliumDotNet::Widget^ get();
		}

		static Window^ Create();
		static Window^ Create(BerkeliumDotNet::Context^ otherContext);

		void AppendWidget(BerkeliumDotNet::Widget^ widget);
		void RemoveWidget(BerkeliumDotNet::Widget^ widget);

		void Focus();
		void Unfocus();

		void MouseMoved(int xPos, int yPos);
		void MouseButton(unsigned int buttonId, bool down);
		void MouseWheel(int xScroll, int yScroll);

		void TextEvent(char event, size_t eventLength);
		void KeyEvent(bool pressed, int modifiers, int vkCode, int scancode);

		void ExecuteJavaScript(String^ javaScript);
		bool NavigateTo(String^ url);
		void Refresh();
		void Resize(int width, int height);

		void SetDelegate(BerkeliumDotNet::WindowDelegate^ windowDelegate);
		void SetTransparent(bool isTransparent);

		void Cut();
		void Copy();
		void Paste();
		void Undo();
		void Redo();
		void Delete();
		void SelectAll();
	};
}
